import { Controller } from 'egg';
import moment from 'moment';
// import tenpay from 'tenpay';
import { ORDER_STATUS_KEYS, SHOP_TYPE, ORDER_TYPE } from '../common/constants';
import xml2json from 'xml2json';
// import fs from 'fs';
// import path from 'path';
import { Op } from 'sequelize';
import { getSign, toPayTime, getCurrentStimp } from '../utils';
import { layout } from '../utils/printUtil';


export default class OrderController extends Controller {
  constructor(ctx) {
    super(ctx);
    // const { payConfig } = this.ctx.app.config;
    // Object.assign(payConfig, { pfx: fs.readFileSync(path.join(__dirname, '../common/1584950371_20200506_cert/apiclient_cert.p12')) });
    // this.ctx.PAYAPI = new tenpay(payConfig);
  }

  async list() {
    const { query } = this.ctx.validateReq('order.list');
    const { page, pageSize, ...where } = query;

    const list = await this.ctx.service.order.list(page, pageSize, where);
    this.ctx.success({
      data: list,
    });
  }


  async ready() {
    const { body } = this.ctx.validateReq('order.ready');
    const update = {
      status: ORDER_STATUS_KEYS.READY
    }
    const data = await this.ctx.service.order.update(body.id, update);
    this.ctx.success({
      data,
    });
  }

  async send() {
    const { body } = this.ctx.validateReq('order.send');
    const { id, shipper_id, shipper_code, shipper_name } = body;
    const update = {
      status: ORDER_STATUS_KEYS.SENDING,
    };

    const order = await this.ctx.model.Order.findOne({ where: { id } });
    if (!order) {
      this.ctx.failure();
      return;
    }
    const time = moment().unix();
    const shipper = {
      order_id: order.order_id,
      shipper_id,
      shipper_code,
      shipper_name,
      add_time: time,
      update_time: time,
    }
    await this.ctx.service.orderExpress.create(shipper);
    const data = await this.ctx.service.order.update(id, update);
    this.ctx.success({
      data,
    });
  }

  // 订单完成
  async finish() {
    const { body } = this.ctx.validateReq('order.finish');
    const { id } = body;
    const update = {
      status: ORDER_STATUS_KEYS.DONE
    }
    const data = await this.ctx.service.order.update(id, update);
    this.ctx.success({
      data,
    });
  }

  // 订单取消
  async cancel() {
    const { body } = this.ctx.validateReq('order.cancel');
    const { id } = body;
    const update = {
      status: ORDER_STATUS_KEYS.CANCEL
    }
    const data = await this.ctx.service.order.update(id, update);
    this.ctx.success({
      data,
    });
  }

  // 微信订单支付
  // async pay() {
  // const { body } = this.ctx.validateReq('order.pay');
  // const {
  //   openId,
  //   // goodsList,
  //   addressId
  // } = body;

  // try {
  //   // 临时订单表
  //   const initOrder = await this.ctx.model.OrderInit.findOne({
  //     where: { user_id: openId }
  //   });

  //   if (!initOrder) return this.ctx.failure({ code: 40000 });

  //   const { cart_id } = initOrder;
  //   const createTime = moment().unix();
  //   const tmpOrder = `${Math.random().toString().slice(-5)}${createTime}`;
  //   const order_id = tmpOrder.substring(tmpOrder.length - 32);
  //   const list: any = [];
  //   // 订单下的商品列表
  //   const goods_list = await this.ctx.model.Cart.findAll({
  //     where: {
  //       id: cart_id.split(',').map(it => parseInt(it)),
  //     },
  //     include: [
  //       {
  //         model: this.ctx.model.GoodsSku,
  //       },
  //       {
  //         model: this.ctx.model.Goods,
  //       }
  //     ]
  //   });
  //   goods_list.forEach(it => {
  //     const { Good, list_pic_url, goods_sku, number, goods_id } = it;
  //     const { name } = Good;
  //     const { composeIds, composeNames, price } = goods_sku;
  //     const item = {
  //       order_id,
  //       goods_id,
  //       goods_compose_ids: composeIds,
  //       goods_compose_names: composeNames,
  //       retail_price: price,
  //       goods_name: name,
  //       list_pic_url,
  //       number
  //     };
  //     list.push(item);
  //   });

  //   // 计算总价
  //   const all_price = list.reduce((pre, next) => pre + next.number * next.retail_price, 0);
  //   const order = {
  //     order_id,
  //     user_id: openId,
  //     create_time: createTime,
  //     all_price,
  //     address_id: addressId,
  //     status: ORDER_STATUS_KEYS.WAIT_PAY
  //   };
  //   // 插入订单表
  //   await this.ctx.service.order.create(order);
  //   await this.ctx.model.OrderGoods.bulkCreate(list);

  //   // 清理未完成的订单
  //   await this.ctx.model.OrderInit.destroy({
  //     where: {
  //       id: initOrder.id
  //     }
  //   });

  //   // 清理购物车已经改变状态的订单
  //   await this.ctx.model.Cart.destroy({
  //     where: {
  //       user_id: openId,
  //       id: {
  //         [Op.in]: initOrder.cart_id.split(',')
  //       }
  //     },
  //   });

  //   // 微信统一下单
  //   const { payInfo: { domain, notify_url } } = this.ctx.app.config;
  //   const result = await this.ctx.PAYAPI.unifiedOrder({
  //     out_trade_no: order_id,
  //     body: list.map(it => it.goods_name).join('-'),
  //     total_fee: all_price * 100,
  //     openid: openId,
  //     notify_url: domain + notify_url
  //   });

  //   this.ctx.success({
  //     data: result,
  //   });
  // } catch (e) {
  //   this.ctx.failure();
  // }
  // }

  // 付款
  // async orderPay() {
  //   const { body: { orderId, openId } } = this.ctx.validateReq('order.id.pay');
  //   const order = await this.ctx.model.Order.findOne({
  //     where: {
  //       order_id: orderId,
  //       user_id: openId
  //     },
  //     include: [
  //       {
  //         model: this.ctx.model.OrderGoods,
  //       }
  //     ],
  //   });
  //   const { user_id, all_price } = order;

  //   const { payInfo: { domain, notify_url } } = this.ctx.app.config;
  //   try {
  //     const result = await this.ctx.PAYAPI.unifiedOrder({
  //       out_trade_no: orderId,
  //       body: order.order_goods.map(it => it.goods_name).join('-'),
  //       total_fee: all_price * 100,
  //       openid: user_id,
  //       notify_url: domain + notify_url
  //     });

  //     this.ctx.success({
  //       data: result,
  //     });
  //   } catch (e) {
  //     this.ctx.failure({
  //       msg: '支付失败'
  //     });
  //   }
  // }


  /**
   * 支付回调
   * return_code SUCCESS/FAIL  此字段是通信标识，非交易标识，交易是否成功需要查看result_code来判断
   * appid  小程序ID
   * mch_id 商户号
   * nonce_str 随机字符串
   * sign 签名
   * sign_type 签名类型	
   * trade_type JSAPI
   * openid 用户标识
   * bank_type 付款银行		 
   * total_fee 订单金额	
   * cash_fee 现金支付金额	
   * transaction_id 微信支付订单号	
   * order_id  商户订单号	
   * time_end 支付完成时间
   */
  async payCallback() {
    const { xml } = JSON.parse(xml2json.toJson(this.ctx.request.body));
    const params: any = {};
    Object.keys(xml).forEach(it => {
      params[it] = xml[it].toString();
    });
    console.log(params, 'params')

    const {
      return_code,
      mch_id,
      openid: user_id,
      sign,
      out_trade_no: order_id,
      bank_type,
      total_fee,
      cash_fee,
      transaction_id,
      time_end,
    } = params;
    const signBody = { ...params };
    delete signBody.sign;

    Object.keys(signBody).forEach(it => {
      if (!signBody[it]) {
        delete signBody[it];
      }
    });
    const order = await this.ctx.model.Order.findOne({
      where: {
        user_id,
        order_id,
      }
    });
    const { partner_key } = await this.ctx.service.shop.merchant.model.findOne({
      where: { id: order.shop_id }
    });

    const paySign = getSign(signBody, partner_key);

    // 支付成功
    if (return_code === 'SUCCESS') {
      // 校验签名
      if (paySign === sign) {
        console.log('签名对比成功');
        // 待支付状态才支付
        if (order && order.status === ORDER_STATUS_KEYS.WAIT_PAY) {
          await this.ctx.model.Order
            .update({
              mch_id,
              total_fee,
              bank_type,
              cash_fee,
              transaction_id,
              pay_time: toPayTime(time_end),
              pay_status: 1, // 支付状态
              status: ORDER_STATUS_KEYS.PAY
            },
              {
                where: {
                  user_id,
                  order_id,
                }
              }
            );

          // 打印小票
          // await this.printMSg(order.id);
          this.ctx.success({
            return_code: 'SUCCESS',
            return_msg: 'OK'
          })
        } else {

          this.ctx.failure({
            return_code: 'FAIL',
            return_msg: '签名失败'
          });
        }
      } else {
        this.ctx.failure({
          return_code: 'FAIL',
          return_msg: '支付失败'
        });
      }
    }
  }

  // 打印小票
  async printMSg(id) {
    try {
      const { feiyun: { url, fei_user: user, fei_ukey } } = this.ctx.app.config;
      const Api = '/Api/Open/';

      // 查询订单信息
      const order = await this.ctx.model.Order.findOne({
        where: { id },
        include: [
          {
            model: this.ctx.model.OrderGoods,
          }
        ],
      });
      const {
        order_goods = [],
        table_number,
        id: orderId,
        order_id,
        shop_id,
        note,
        order_type,
        table_cost,
        pack_cost,
        all_price,
        meal_number
      } = order;


      const shop = await this.ctx.service.shop.merchant.model.findOne({
        where: { id: shop_id }
      });
      const { fei_sn, type, name } = shop;

      const stime = getCurrentStimp();
      const sig = this.ctx.helper.encry('sha1', user + fei_ukey + stime);

      const goodsList = order_goods.map(ot => ({
        name: ot.goods_name,
        price: ot.price / 100,
        num: ot.number
      }));



      const [CATERING, OTHER] = SHOP_TYPE;
      const [, TAKEOUT] = ORDER_TYPE;

      let address = '-';
      let phone = '-';
      // 商铺类型 餐饮 + 外卖 || 其他 
      if ((type === CATERING && order_type === TAKEOUT) || type === OTHER) {
        const addressInfo = await this.ctx.model.OrderAddress.findOne({ where: { order_id } });
        if (addressInfo) {
          const { address_name, address_detail, mobile } = addressInfo || {};
          address = address_detail + address_name;
          phone = mobile;
        }
      }

      const conList = layout(
        goodsList,
        `${table_number}号桌`,
        {
          note,
          address,
          phone,
          order_type,
          table_cost,
          pack_cost,
          all_price,
          meal_number,
          name
        }
      )

      const result = await this.ctx.curl(url + Api, {
        method: 'POST',
        dataType: 'json',
        data: {
          user,
          stime,
          sig,
          apiname: 'Open_printMsg',
          sn: fei_sn,
          content: conList.join(''),
        }
      });

      const { data: { ret, msg } } = result;

      if (ret === 0) {
        // TAKEOUT
        // 餐饮类型商铺 && 堂食订单:  打印订单后，将订单状态从支付->完成
        // if (type === CATERING && order_type === INSTORE) {
        //   await this.ctx.model.Order.update({ status: ORDER_STATUS_KEYS.DONE }, { where: { id } });
        // }

        this.ctx.success({ msg });
        this.ctx.app.logger.info(`订单ID-${orderId}，打印小票成功`);
        return;
      }
    } catch (e) {
      this.ctx.app.logger.error(`订单ID-${id}，打印小票失败，失败原因${e}`);
      throw e;
    }
  }


  async refund() {
    // const { body: { orderId, openId } } = this.ctx.validateReq('order.pay.refund');
    // console.log(orderId, openId);
    // const order = await this.ctx.model.Order.findOne({
    //   where: {
    //     order_id: orderId,
    //     user_id: openId
    //   }
    // });

    // const {
    //   transaction_id,
    //   total_fee,
    //   status
    // } = order;

    // if (status !== ORDER_STATUS_KEYS.PAY) {
    //   this.ctx.failure();
    //   return;
    // }


    // const createTime = moment().unix();
    // // 退款单号
    // const out_refund_no = `${Math.random().toString().slice(-5)}${createTime}`;
    // try {
    //   const result = await this.ctx.PAYAPI.refund({
    //     transaction_id,
    //     out_refund_no,
    //     total_fee,
    //     refund_fee: total_fee
    //   });
    //   const { return_code, return_msg } = result;
    //   if (return_code === 'SUCCESS') {
    //     const update = {
    //       out_refund_no,
    //       status: ORDER_STATUS_KEYS.CANCEL
    //     }
    //     this.ctx.model.Order
    //       .update({ ...update },
    //         {
    //           where: {
    //             order_id: orderId
    //           }
    //         }
    //       )
    //     this.ctx.success();
    //     return;
    //   }
    //   this.ctx.failure({
    //     msg: return_msg
    //   });
    // } catch (e) {
    //   this.ctx.failure({
    //     msg: '退款失败'
    //   });
    // }
  }

  async submit() {
    // const { body } = this.ctx.validateReq('order.submit');
    // const { user_id } = body;

    // const isExit = await this.ctx.model.OrderInit.findOne({
    //   where: { user_id }
    // });

    // let result = {};
    // if (isExit) {
    //   result = await this.ctx.model.OrderInit.update(
    //     body,
    //     {
    //       where: {
    //         user_id
    //       }
    //     }
    //   );
    // } else {
    //   result = await this.ctx.model.OrderInit.create(body);
    // }
    const result = {};
    if (result) {
      this.ctx.success({
        data: result
      });
    }
  }


  async orderDetail() {
    const { params: { id } } = this.ctx.validateReq('order.detail');

    const data = await this.ctx.service.order.detail(id);
    this.ctx.success({
      data,
    });
  }


  async submitDetail() {
    // const { query: { user_id } } = this.ctx.validateReq('order.submit.detail');
    // const order = await this.ctx.model.OrderInit.findOne({
    //   where: { user_id }
    // });

    // if (!order) {
    //   this.ctx.failure();
    //   return;
    // }

    // const { cart_id, all_price } = order;
    // const cartIds = cart_id.split(",");
    // const goodsList = await this.ctx.model.Cart.findAll({
    //   where: {
    //     user_id,
    //     id: { [Op.in]: cartIds },
    //   },
    //   include: [{ model: this.ctx.model.GoodsSku }],
    // });
    // // 地址
    // const address = await this.ctx.model.Address.findOne({
    //   where: { user_id }
    // });

    // this.ctx.success({
    //   data: {
    //     goodsList,
    //     address,
    //     all_price
    //   }
    // })

  }

}